package actions.register;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.io.FileUtils;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.security.Identity;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

import utils.Propiedades;
import domain.Foto;
import domain.Mesa;
import domain.Municipio;
import domain.Perfil;
import domain.Provincia;
import domain.Restaurante;
import domain.Usuario;

@Name("registerRestaurant")
@Scope(ScopeType.CONVERSATION)
@SuppressWarnings("all")
public class RegisterRestaurantAction implements Serializable {

	private static final long serialVersionUID = 8377260917766231287L;

	@In
	FacesMessages facesMessages;

	@In
	EntityManager em;

	@In(required = false)
	Usuario usuarioAutenticado; // usuario autenticado

	@In(required = false)
	private Restaurante restaurant = new Restaurante();

	@In(required = false)
	private Mesa table = new Mesa();

	@In(required = false)
	private Mesa smokingTable = new Mesa();

	// Datos del restaurante
	private Provincia provinciaRestaurante;
	private Municipio municipioRestaurante;
	private Integer numMesas;
	private Integer numMesasFumadores;
	private List<Mesa> mesasRestaurante = new ArrayList<Mesa>(0);

	@DataModel
	private Set<Foto> fotosRestauranteRegistrar = new HashSet<Foto>(0);
	
	@DataModelSelection("fotosRestauranteRegistrar")
	private Foto foto;
	
	private String fotoSeleccionada;

	@DataModel
	private List<Mesa> mesasFumadores = new ArrayList<Mesa>(0);

	@DataModel("mesasNoFumadores")
	private List<Mesa> mesasNoFumadores = new ArrayList<Mesa>(0);

	@DataModelSelection("mesasNoFumadores")
	private Mesa noSmokingTableList;

	@DataModelSelection("mesasFumadores")
	private Mesa smokingTableList;

	// Subida de fotos
	private List<UploadItem> fileList = new ArrayList<UploadItem>();
	private final int maxFiles = Integer.valueOf(Propiedades.getInstance().getPropiedad("maxFotos"));

	/***************************************************************************
	 * Indica si la provincia seleccionada cambia para reducir el acceso a la
	 * tabla municipios
	 **************************************************************************/

	Provincia ultimaProvinciaSeleccionada = new Provincia();

	// Lista de Municipios para Mostrar al Usuario
	List<Municipio> municipios;

	public String register() {
		if (!restaurant.isPermiteFumadores() && !mesasFumadores.isEmpty()) {
			facesMessages
					.add("Ha especificado que no posee zona de fumadores, sin embargo, hay mesas registradas para fumadores,"
							+ " por favor, elimine las mesas o desactive la casilla de zona de fumadores");
			return null;
		}

		if (validateData()) {
			try {

				restaurant.setMunicipio(municipioRestaurante);
				restaurant.setRevisado(false);

				em.persist(restaurant);

				// perfil
				Perfil p = new Perfil();
				p.setRestaurante(restaurant);
				p.setNombre("OWNER_" + restaurant.getRestaurante());
				em.persist(p);

				Usuario u = em.find(Usuario.class, usuarioAutenticado
						.getUsuario());
				u.setPerfil(p);

				// fotos
				for (Iterator it = fotosRestauranteRegistrar.iterator(); it
						.hasNext();) {
					Foto f = (Foto) it.next();
					f.setRestaurante(restaurant);
				}
				// mesas
				for (Iterator it = mesasRestaurante.iterator(); it.hasNext();) {
					Mesa m = (Mesa) it.next();
					m.setRestaurante(restaurant);
				}

				restaurant.getFotos().addAll(fotosRestauranteRegistrar);
				restaurant.getMesas().addAll(mesasRestaurante);

				em.flush();

				// em.merge(restaurant);

				return "restaurantRegistered";
			} catch (Exception e) {
				e.printStackTrace();

			}
		}
		return null;

	}

	@End
	public String confirm() {
		return "login";
	}

	@End
	public String cancel() {
		Identity.instance().logout();
		return "login";
	}

	@SuppressWarnings("unchecked")
	public List<Municipio> findMunicipios() {

		if (provinciaRestaurante != null) {
			if (ultimaProvinciaSeleccionada.getProvincia() != provinciaRestaurante
					.getProvincia()) { // Si el usuario selecciona otra
				// provincia
				municipios = (List<Municipio>) em.createQuery(
						"FROM Municipio m WHERE m.provincia.provincia = "
								+ provinciaRestaurante.getProvincia())
						.getResultList();
				ultimaProvinciaSeleccionada.setProvincia(provinciaRestaurante
						.getProvincia());
			}
		} else
			// Si no hay provincia seleccionada
			municipios = new ArrayList<Municipio>();

		return municipios;
	}

	public boolean validateData() {
		if (invalid(restaurant.getNombre())) {
			facesMessages.addToControlFromResourceBundle("regRestaurantName",
					"mandatory");

			return false;
		}
		if (invalid(restaurant.getEmail())) {
			facesMessages.addToControlFromResourceBundle("regEmail",
					"mandatory");
			return false;

		}
		if (invalid(restaurant.getTelefono())) {
			facesMessages.addToControlFromResourceBundle("regPhone",
					"mandatory");
			return false;
		}

		if (restaurant.getCategoria() == null) {
			facesMessages.addToControlFromResourceBundle("regCategory",
					"mandatory");
			return false;
		}

		if (this.getMunicipioRestaurante() == null) {
			facesMessages.addToControlFromResourceBundle("regMunicipio",
					"mandatory");
			return false;
		}

		if (this.getProvinciaRestaurante() == null) {
			facesMessages.addToControlFromResourceBundle("regProvincias",
					"mandatory");
			return false;
		}
		return true;
	}

	public void addTable() {
		if (table.getCodigo() == null)
			facesMessages.addToControl("comensales", "mandatory");
		else {
			table.setPermiteFumar(false);
			mesasRestaurante.add(table);
			try {
				mesasNoFumadores.add((Mesa) BeanUtils.cloneBean(table));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void addSmokingTable() {
		if (smokingTable.getCodigo() == null)
			facesMessages.addToControl("comensalesFumadores", "mandatory");
		else {
			smokingTable.setPermiteFumar(true);
			mesasRestaurante.add(smokingTable);
			try {
				mesasFumadores.add((Mesa) BeanUtils.cloneBean(smokingTable));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void uploadFiles(UploadEvent ue) {
		// TODO Investigar como obtener la ruta absoluta para crear un File
		String rutaBase = ((HttpServletRequest) FacesContext
				.getCurrentInstance().getExternalContext().getRequest())
				.getRealPath("/RestaurantsImages");
		byte[] datos;
		UploadItem file = (UploadItem) ue.getUploadItem();

		String rutaFichero = "/Irestaurant-" + (int) (Math.random() * 1000000)
				+ "-" + file.getFileName().replaceAll(" ", "_");
		File f = new File(rutaBase + rutaFichero);

		Foto foto = new Foto();
		foto.setRuta(rutaFichero);

		fotosRestauranteRegistrar.add(foto);

		try {
			datos = FileUtils.readFileToByteArray(file.getFile());
			FileUtils.writeByteArrayToFile(f, datos);

		} catch (IOException e) {
			e.printStackTrace();

		}

	}
	
	
	public void deletePicture(){
		fotosRestauranteRegistrar.remove(foto);
	}

	public void seleccionarFoto(String seleccion) {
		this.setFotoSeleccionada(seleccion);
	}

	public void removeTables() {
		mesasNoFumadores.remove(noSmokingTableList);
	}

	public void removeSmokingTables() {
		mesasFumadores.remove(smokingTableList);
	}

	// Metodos auxiliares

	boolean invalid(String field) {
		return (field == null || field.equals(""));
			
	}

	/***************************************************************************
	 * Getters & Setters
	 **************************************************************************/

	public Provincia getProvinciaRestaurante() {
		return provinciaRestaurante;
	}

	public void setProvinciaRestaurante(Provincia provinciaRestaurante) {
		this.provinciaRestaurante = provinciaRestaurante;
	}

	public Municipio getMunicipioRestaurante() {
		return municipioRestaurante;
	}

	public void setMunicipioRestaurante(Municipio municipioRestaurante) {
		this.municipioRestaurante = municipioRestaurante;
	}

	public Integer getNumMesas() {
		return numMesas;
	}

	public void setNumMesas(Integer numMesas) {
		this.numMesas = numMesas;
	}

	public Integer getNumMesasFumadores() {
		return numMesasFumadores;
	}

	public void setNumMesasFumadores(Integer numMesasFumadores) {
		this.numMesasFumadores = numMesasFumadores;
	}

	public List getFileList() {
		return fileList;
	}

	public void setFileList(List fileList) {
		this.fileList = fileList;
	}

	public int getMaxFiles() {
		return maxFiles;
	}

	public String getFotoSeleccionada() {
		return fotoSeleccionada;
	}

	public void setFotoSeleccionada(String fotoSeleccionada) {
		this.fotoSeleccionada = fotoSeleccionada;
	}

}
